package com.konsung.ksdc.common.utils;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.webkit.MimeTypeMap;
import android.widget.Toast;

import com.konsung.ksdc.R;
import com.konsung.ksdc.bean.netbean.UpdateMessageNetBean;
import com.konsung.ksdc.common.network.MyFileCallBack;
import com.konsung.ksdc.common.network.RequestCallback;
import com.konsung.ksdc.common.network.RequestUtils;
import com.konsung.ksdc.common.network.ResponseBean;
import com.konsung.ksdc.config.MyApplication;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import okhttp3.Call;

/**
 * Created by liangkun on 2017/4/26 0026.
 * 升级管理器
 */

public class UpgradeUtils {
    private static final int TYPE_SHOW_ERROR = 100;
    private static final int TYPE_SHOW_UPDATE_DIALOG = 101;
    private static final int TYPE_SHOW_UPDATE_SILENT = 103;
    private static final String TAG = "UpgradeUtils";
    protected Context mContext;
    public boolean isInApp; //标记是否使用应用
    public boolean isDowned; //标记apk是否已经下载/安装后为false
    private String md5;
    private int localVersionCode;
    private String versionDesc;
    private String apkName;
    private String localApkName;
    private int netVersionCode;
    private int apkSize;
    private boolean isForce; //是否强制升级
    public NetWifiConnectReceiver wifiReceiver;
    public DownApkTask downApkTask; //下载任务
    private boolean isFirstMobile; //没连wifi,连接手机,第一次弹窗，wifi广播屏蔽
    private boolean isOnce; //网络状态发生改变，弹窗消息只发送一次，避免多次弹窗
    public ProgressDialog progressDialog;
    private int downProgress;
    private AlertDialog dialog = null;
    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case TYPE_SHOW_UPDATE_DIALOG:
                    isOnce = true; //禁止弹第二遍
                    if (Constants.isupdating) {
//                        startHealthOneDownloadThread();
                        downApkTask.start();
                    } else {
                        showUpdateDialog(isForce);
                    }
                    break;
                case TYPE_SHOW_ERROR:
                    // 失败
                    ToastUtils.toastContent(mContext, msg.obj + "");
                    break;
                case TYPE_SHOW_UPDATE_SILENT:
                    //是否走静默下载
                    downApkTask.start();
                    break;

                default:
                    break;
            }
        }
    };

    /**
     * @param context 上下文
     */
    public UpgradeUtils(Context context) {
        mContext = context;
        progressDialog = new ProgressDialog(context);
        localVersionCode = PackageUtils.getVersionCode(context);
        if (downApkTask == null) {

            downApkTask = new DownApkTask();
        }
    }

    /**
     * 查找是否升级
     */
    public void findUpdateMessage() {
        RequestUtils.findUpgradeMessage(new RequestCallback() {
            @Override
            public void onError(Call call, Exception e) {
            }

            @Override
            public void onResponse(ResponseBean responseBean) {
                String resultCode = responseBean.getResultCode();
                if (resultCode.equals(Constants.REQUEST_OK)) {
                    UpdateMessageNetBean bean = responseBean.getEntity(UpdateMessageNetBean.class);
                    if (null != bean) {
                        String netCode = bean.getUpgradeVersion();
                        versionDesc = bean.getUpgradeMsg();
                        apkName = bean.getApkName();
                        isForce = bean.getForce();
                        md5 = bean.getMd5();
                        String size = bean.getApkSize();
                        if (!TextUtils.isEmpty(size)) {
                            apkSize = Integer.valueOf(size);
                        }
                        if (!TextUtils.isEmpty(netCode)) {
                            netVersionCode = Integer.valueOf(netCode);
                        }
                        localApkName = netVersionCode + "_" + bean.getApkName();

                        if (netVersionCode > localVersionCode) {
                            /**当有数据的时候
                             * 注册网络状态广播
                             */
                            dynamicRegister();
                        }
                    }
                }
            }
        });
    }

    /**
     * 注册动态网路连接广播
     */
    private void dynamicRegister() {
        wifiReceiver = new NetWifiConnectReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        mContext.registerReceiver(wifiReceiver, filter);
    }

    /**
     * wifi广播
     */
    public class NetWifiConnectReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Constants.isNetConnect = RequestUtils.isNetworkConnected(MyApplication.getContext());
            // 这个监听网络连接的设置，wifi以及移动网络的打开和关闭
            if (!RequestUtils.isNetworkConnected(MyApplication.getContext())) {
                return;
            }
            /**
             * wifi情况下静默下载
             */
            if (RequestUtils.isWifiAvailable(MyApplication.getContext())) {

                if (!isFirstMobile) {

                    mHandler.sendEmptyMessage(TYPE_SHOW_UPDATE_SILENT);
                }

                return;
            } else {
                downApkTask.stop();
            }
            /**
             * wifi断掉，且移动数据可用
             */

            if (RequestUtils.isMobileAvailable(MyApplication.getContext())) {
                //发现网络状态改变
                if (!isOnce) {
                    mHandler.sendEmptyMessage(TYPE_SHOW_UPDATE_DIALOG);
                }
            }
        }
    }

    /**
     * 下载任务
     */
    public class DownApkTask extends Handler implements Runnable {

        @Override
        public void run() {
            checkDownloadCache();
        }

        /**
         * 开启下载
         */
        public void start() {
            removeCallbacks(this);
//          2秒后开启
            postDelayed(this, 2000);
        }

        /**
         * 停止下载
         */
        public void stop() {
            //清除该任务
            removeCallbacks(this);
            removeMessages(TYPE_SHOW_UPDATE_SILENT);
            isInApp = false;
        }
    }

    /**
     * 检查是否有下载缓存
     */
    public void checkDownloadCache() {
        File file = new File(Environment.getExternalStorageDirectory()
                .getAbsolutePath(), localApkName);
        //查看本地和实时进度
        // ### 如果这个下载文件不存在或者长度 ###
        if (!file.exists() && file.length() <= 0) {
            updateApk(0, localApkName);
            return;
        }
        if (PreferenceUtils.getInt(mContext, Constants.VERVISONCODE, 1) <
                netVersionCode) {
            if (file.length() > apkSize) {
                file.delete();
            }
            if (file.exists() && file.isFile()) {
                updateApk((int) file.length(), "temp" + localApkName);
            }
        } else {
            //（由于wifi和手机切发3次广播，就会有3个进度条，缓存混乱，已经用2个boolen
            // 值做判断避免多次弹出来）万不得已，缓存数据》apk包，删掉
            if (file.length() > apkSize) {
                file.delete();
            }
            updateApk((int) file.length(), "temp" + localApkName);
            //下载的文件放到temp文件中
        }
    }

    /**
     * 完整的下载任务
     * @param size 下载的apk文件大小
     * @param fileName 要下载的文件名
     */

    protected void updateApk(final int size, String fileName) {
        //如果wifi开启，静默下载apk,wifi没开始，显示更新进度dialog
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(true);
        progressDialog.setMax(apkSize);
        progressDialog.setProgress(size);

        if (!RequestUtils.checkNetwork(mContext)) {
            hideDialog();
            return;
        }

        if (RequestUtils.isWifiAvailable(mContext)) {
            progressDialog.hide();
            //wifi开启的时候，不在弹3次静默下载，避免线程缓存混乱
            isFirstMobile = true;
            isOnce = false;
        } else {
            progressDialog.hide();
        }

        Constants.isupdating = true;

        // 下载
        RequestUtils.downloadApk(apkName, "" + size, new MyFileCallBack(Environment
                .getExternalStorageDirectory().getAbsolutePath(),
                fileName) {
            @Override
            public void inProgress(float var1, long var2) {
                //有wifi不显示进度条
                if (!RequestUtils.isWifiAvailable(mContext)) {
                    downProgress = (int) (var1 * apkSize);
                    //记录下载的缓存
                    progressDialog.setProgress(downProgress + size);
                }
            }

            @Override
            public void onError(Call call, Exception e) {
                //每次wifi与流量切换会走onError
                downApkTask.stop();
                Constants.isupdating = false;
                hideDialog();

                if (RequestUtils.isMobileAvailable(MyApplication.getContext())) {
                    Toast.makeText(mContext, R.string.tip_download_error,
                            Toast.LENGTH_SHORT).show();
                }

                // ### 下载失败后也把下载的文件拷贝过去 ###
                File tempFile = new File(Environment
                        .getExternalStorageDirectory()
                        .getAbsolutePath(), "temp" + localApkName);
                File srcFile = new File(Environment
                        .getExternalStorageDirectory()
                        .getAbsolutePath(), localApkName);
                if (srcFile.exists() && tempFile.exists() && srcFile.length()
                        > 0 && tempFile.length() > 0) {
                    copyFile(srcFile, tempFile);
                }
            }

            @Override
            public void onResponse(File file) {
                hideDialog();
                //临时文件
                File tempFile = new File(Environment
                        .getExternalStorageDirectory()
                        .getAbsolutePath(), "temp" + localApkName);
                //本地文件
                File srcFile = new File(Environment
                        .getExternalStorageDirectory()
                        .getAbsolutePath(), localApkName);
                //查看下载本地文件名
                if (file.equals(tempFile)) {

                    copyFile(srcFile, tempFile);
                }

                Constants.isupdating = true;
                if (tempFile.exists()) {
                    tempFile.delete();
                }
                PreferenceUtils.putInt(mContext, Constants.VERVISONCODE, netVersionCode);
                if (srcFile.length() == apkSize) {
                    //验证下载的文件md5完整性
                    try {
                        String updateMd5 = getFileMD5(srcFile);
                        //获取下载的apk md5值
                        if (updateMd5.equalsIgnoreCase(md5)) {
                            //已下载apk的标记
                            isDowned = true;
                            if (isInApp) {
                                installAPK(srcFile, mContext);
                            }
                        } else {
                            srcFile.delete(); //删除apk
                            if (RequestUtils.isWifiAvailable(MyApplication
                                    .getContext())) {
                                //发现网络状态改变,重新静默下载
                                mHandler.sendEmptyMessage(TYPE_SHOW_UPDATE_SILENT);
                                return;
                            }

                            if (RequestUtils.isMobileAvailable(MyApplication
                                    .getContext())) {
                                //发现网络状态改变,重新流量弹窗
                                mHandler.sendEmptyMessage(TYPE_SHOW_UPDATE_DIALOG);
                            }
                        }
                    } catch (NoSuchAlgorithmException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    /**
     * 显示更新dialog
     * @param isForce 是否强制升级
     */
    private void showUpdateDialog(boolean isForce) {
        isFirstMobile = true;
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setCancelable(false);
        // 1.设置title
        builder.setTitle(R.string.dialog_update_title);
        // 2.设置内容
        builder.setMessage(versionDesc + mContext.getString(R.string.need) +
                Formatter.formatFileSize(MyApplication.getContext(), apkSize) + mContext.getString(R
                .string.ask));
        //强制升级
        if (isForce) {
            builder.setPositiveButton(R.string.btn_update_now, new
                    DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //重新赋值，如果开启wifi就使用wifi流量
                            isFirstMobile = false;
                            isOnce = false; //如果断开wifi，重新启用手机流量
                            if (RequestUtils.isWifiAvailable(MyApplication
                                    .getContext())) {
                                ToastUtils.toastContent(mContext, R.string.backstage + "");
                            }
                            downApkTask.start();
                        }
                    });
        } else {
            // 3.设置按钮
            builder.setNegativeButton(R.string.btn_update_later, new
                    DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            isFirstMobile = false;
                            isOnce = false;
                        }
                    });
            builder.setPositiveButton(R.string.btn_update_now, new
                    DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            isFirstMobile = false;
                            isOnce = false;
                            if (RequestUtils.isWifiAvailable(MyApplication
                                    .getContext())) {
                                ToastUtils.toastContent(mContext, R.string.backstage + "");
                            }
                            downApkTask.start();
                        }
                    });
        }

        builder.show();
    }

    /**
     * 文件对拷
     * @param src 源文件
     * @param copy 拷贝文件
     */
    private void copyFile(File src, File copy) {
        BufferedInputStream in = null;
        BufferedOutputStream out = null;

        try {
            in = new BufferedInputStream(new FileInputStream(copy));
            out = new BufferedOutputStream(new FileOutputStream(src, true));

            byte[] buf = new byte[1024];
            int len = -1;
            while (((len = in.read(buf)) != -1) && (len > 0)) {
                out.write(buf, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 安装app
     * @param file app文件对象
     * @param context 上下文
     */
    private void installAPK(File file, Context context) {
        //安装后显示false
        isDowned = false;
        if (Build.VERSION.SDK_INT < 23) {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setComponent(new ComponentName("com.android" +
                    ".packageinstaller",
                    "com.android.packageinstaller.PackageInstallerActivity"));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(file), "application/vnd" +
                    ".android" +
                    ".package-archive");
            mContext.startActivity(intent);
        } else {
            File srcFile = new File(Environment
                    .getExternalStorageDirectory()
                    .getAbsolutePath(), localApkName);
            if (srcFile.exists()) {
                openFile(srcFile, context);
            }
        }
    }

    /**
     * @param file apk
     * @return md5数据
     * @throws NoSuchAlgorithmException 异常
     * @throws IOException 异常
     */
    private static String getFileMD5(File file) throws NoSuchAlgorithmException, IOException {
        if (!file.isFile()) {
            return null;
        }
        MessageDigest digest;
        FileInputStream in;
        byte[] buffer = new byte[1024];
        int len;
        digest = MessageDigest.getInstance("MD5");
        in = new FileInputStream(file);
        while ((len = in.read(buffer, 0, 1024)) != -1) {
            digest.update(buffer, 0, len);
        }
        in.close();
        BigInteger bigInt = new BigInteger(1, digest.digest());
        return bigInt.toString(16);
    }

    /**
     * 打开往哪见
     * @param file 文件
     * @param context 上下文
     */
    public void openFile(File file, Context context) {

        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction("android.intent.action.VIEW");
        String type = getMIMEType(file);
        intent.setDataAndType(Uri.fromFile(file), type);
        try {
            context.startActivity(intent);
        } catch (Exception var5) {
            Toast.makeText(context, "没有找到打开此类文件的程序",
                    Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * @param var0 文件
     * @return string
     */
    public String getMIMEType(File var0) {
        String var1 = "";
        String var2 = var0.getName();
        String var3 = var2.substring(var2.lastIndexOf(".") + 1, var2.length()
        ).toLowerCase();
        var1 = MimeTypeMap.getSingleton().getMimeTypeFromExtension(var3);
        return var1;
    }

    /**
     * 隐藏dialog
     */
    private void hideDialog() {
        if (dialog != null) {
            dialog.hide();
        }
        if (progressDialog != null) {
            progressDialog.hide();
        }
    }
}
